package com.haust.dianqi.web;

import com.alibaba.fastjson.JSONObject;
import com.haust.dianqi.pojo.User;
import com.haust.dianqi.pojo.UserFile;
import com.haust.dianqi.service.UserFileService;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @Auther: csp1999
 * @Date: 2020/04/27/9:42
 * @Description:
 */
@Controller
@RequestMapping("/file")
public class FileController {

    @Autowired
    private UserFileService userFileService;

    /**
     * @方法描述: 返回当前用户的所有文件列表，并以json格式返回
     * @参数集合: [session, model]
     * @返回类型: java.util.List<com.haust.entity.UserFile>
     * @作者名称: csp1999
     * @日期时间: 2020/4/27 16:13
     */
    @GetMapping("/findAllJSON")
    @ResponseBody
    public List<UserFile> findAllJSON(HttpSession session, Model model) {
        //在登录的session中获取用户的id
        User user = (User) session.getAttribute("user");
        System.out.println(user);
        //根据用户id查询所有的文件信息
        List<UserFile> userFiles = userFileService.findByUserId(user.getId());
        return userFiles;
    }

//    /**
//     * @方法描述: 查询所有
//     * @参数集合: [session, model]
//     * @返回类型: java.lang.String
//     * @作者名称: csp1999
//     * @日期时间: 2020/4/27 10:38
//     */
//    @GetMapping("/showAll")
//    public String findAll(HttpSession session, Model model) {
//        //在登录的session中获取用户的id
//        User user = (User) session.getAttribute("user");
//        //根据用户id查询所有的文件信息
//        List<UserFile> userFiles = userFileService.findByUserId(user.getId());
//        //存入作用域中
//        model.addAttribute("files", userFiles);
//        return "/admin/addArticle";
//    }

    /**
     * @方法描述: (文章附件)文件上传操作
     * @参数集合: [newfile, session]
     * @返回类型: java.lang.String
     * @作者名称: csp1999
     * @日期时间: 2020/4/27 11:17
     */
    @PostMapping("/upload")
    public String upload(MultipartFile newfile, HttpSession session) throws IOException {//注意：参数名newfile 应该与上传表单的name属性名一直

        //从session中获取user数据
        User user = (User) session.getAttribute("user");

        String oldFilename = newfile.getOriginalFilename();//获取文件的原始名称
        String extension = "." + FilenameUtils.getExtension(oldFilename);//获取文件的后缀(FilenameUtils工具类需要引入commons-upload坐标依赖)

        //生成新文件的名称（时间戳格式）
        String newFilename = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
                + UUID.randomUUID().toString().replace("-", "") + extension;

        long size = newfile.getSize();//文件大小
        String type = newfile.getContentType(); //文件类型

        //处理根据日期生成目录
        String realPath = ResourceUtils.getURL("classpath:").getPath() + "static/upload";//由相对路径获取绝对路径方式一
        //用url.getPath()获取到的路径被utf-8编码了，用URLDecoder.decode(p, "UTF-8")即可解码
        String decoderRealPath = URLDecoder.decode(realPath, "UTF-8");

        //String realPath = session.getServletContext().getRealPath("/files");//由相对路径获取绝对路径方式二
        String dateDirPath = decoderRealPath + "/" + new SimpleDateFormat("yyyy-MM-dd").format(new Date());//日期文件夹路径

        //路径解码测试
        System.out.println("realpath:" + decoderRealPath);
        System.out.println(dateDirPath);
        //测试原路径
        System.out.println("realPath=" + realPath);

        File dateDir = new File(dateDirPath);//日期文件夹
        if (!dateDir.exists()) dateDir.mkdirs();

        //处理文件上传操作
        newfile.transferTo(new File(dateDir, newFilename));

        //将文件信息放入数据库并保存
        UserFile userFile = new UserFile();
        userFile.setOldFilename(oldFilename);
        userFile.setNewFilename(newFilename);
                userFile.setExt(extension);
                userFile.setSize(String.valueOf(size));
                userFile.setType(type);
                userFile.setPath("/upload/"
                + new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
                userFile.setUserid(user.getId());
        userFileService.save(userFile);

        //重定向addArticle
        return "redirect:/addArticle";
    }

    /**
     * editormd 文章内容中的图片上传
     *
     * @param: file
     * @param: request
     * @return: JSONObject
     * @create: 2020/10/10 12:14
     * @author: csp1999
     */
    @RequestMapping("/articleImg/upload")
    @ResponseBody
    public JSONObject fileUpload(@RequestParam(value = "editormd-image-file", required = true) MultipartFile file, HttpServletRequest request) throws IOException {
        String oldFilename = file.getOriginalFilename();//获取文件的原始名称
        String extension = "." + FilenameUtils.getExtension(oldFilename);//获取文件的后缀(FilenameUtils工具类需要引入commons-upload坐标依赖)

        //生成新文件的名称（时间戳格式）
        String newFilename = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
                + UUID.randomUUID().toString().replace("-", "") + extension;
        //处理根据日期生成目录
        String realPath = ResourceUtils.getURL("classpath:").getPath() + "static/upload";//由相对路径获取绝对路径方式一
        //用url.getPath()获取到的路径被utf-8编码了，用URLDecoder.decode(p, "UTF-8")即可解码
        String decoderRealPath = URLDecoder.decode(realPath, "UTF-8");

        //String realPath = session.getServletContext().getRealPath("/files");//由相对路径获取绝对路径方式二
        String dateDirPath = decoderRealPath + "/" + new SimpleDateFormat("yyyy-MM-dd").format(new Date());//日期文件夹路径

        File dateDir = new File(dateDirPath);//日期文件夹
        if (!dateDir.exists()) dateDir.mkdirs();

        //处理文件上传操作
        file.transferTo(new File(dateDir, newFilename));

        //${#servletContext.contextPath}+${file.path}+'/'+${file.newFilename}
        String serverAddress = "http://localhost:8080/";
        String classpath = request.getServletContext().getContextPath();
        String filePath = "/upload/" + new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String imgUrl = classpath+filePath+"/"+newFilename;

        //给editormd进行回调
        JSONObject res = new JSONObject();
        res.put("url", imgUrl);
        res.put("success", 1);
        res.put("message", "upload success!");

        return res;
    }

    /**
     * @方法描述: 文件下载
     * @参数集合: [id, response]
     * @返回类型: void
     * @作者名称: csp1999
     * @日期时间: 2020/4/27 15:50
     */
    @GetMapping("/download")
    public void download(String id, HttpServletResponse response) throws IOException {//get方法传入的id类型为string
        //获取文件信息
        UserFile userFile = userFileService.findById(id);
        //更新下载次数
        userFile.setDowncounts(userFile.getDowncounts() + 1);
        userFileService.update(userFile);

        //根据文件信息中文件的名字 和 文件存储路径获取文件输入流
        String realPath = ResourceUtils.getURL("classpath:").getPath() + "static/" + userFile.getPath();
        String decodeRealPath = URLDecoder.decode(realPath, "utf-8");//解码

        //附件下载(给文件名编码，防止乱码 ininle)
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(userFile.getOldFilename(), "utf-8"));

        //获取文件输入流
        FileInputStream fileInputStream = new FileInputStream(new File(decodeRealPath, userFile.getNewFilename()));
        //获取响应输出流
        ServletOutputStream outputStream = response.getOutputStream();
        //文件拷贝
        IOUtils.copy(fileInputStream, outputStream);
        IOUtils.closeQuietly(fileInputStream);
        IOUtils.closeQuietly(outputStream);
    }

    /**
     * @方法描述: 文件在线浏览
     * @参数集合: [id, response]
     * @返回类型: void
     * @作者名称: csp1999
     * @日期时间: 2020/4/27 15:55
     */
    @GetMapping("/openinline")
    public void openinline(String id, HttpServletResponse response) throws IOException {//get方法传入的id类型为string
        //获取文件信息
        UserFile userFile = userFileService.findById(id);

        //根据文件信息中文件的名字 和 文件存储路径获取文件输入流
        String realPath = ResourceUtils.getURL("classpath:").getPath() + "static/" + userFile.getPath();
        String decodeRealPath = URLDecoder.decode(realPath, "utf-8");//解码

        //附件下载(给文件名编码，防止乱码)
        response.setHeader("content-disposition", "inline;filename=" + URLEncoder.encode(userFile.getOldFilename(), "utf-8"));

        //获取文件输入流
        FileInputStream fileInputStream = new FileInputStream(new File(decodeRealPath, userFile.getNewFilename()));
        //获取响应输出流
        ServletOutputStream outputStream = response.getOutputStream();
        //文件拷贝
        IOUtils.copy(fileInputStream, outputStream);
        IOUtils.closeQuietly(fileInputStream);

    }

    /**
     * @方法描述: 文件删除
     * @参数集合: [id]
     * @返回类型: java.lang.String
     * @作者名称: csp1999
     * @日期时间: 2020/4/27 16:10
     */
    @GetMapping("/delete")
    public String delete(String id) throws UnsupportedEncodingException, FileNotFoundException {
        //根据id查询信息
        UserFile userFile = userFileService.findById(id);

        //删除文件
        //1.先获取服务器下文件位置的绝对路径
        String realPath = ResourceUtils.getURL("classpath:").getPath() + "static/" + userFile.getPath();
        String decodeRealPath = URLDecoder.decode(realPath, "utf-8");//解码
        //2.获取文件，并删除
        File file = new File(decodeRealPath, userFile.getNewFilename());
        if (file.exists()) file.delete();

        //删除数据库中的记录
        userFileService.delete(id);
        //重定向addArticle
        return "redirect:/addArticle";
    }
}
